#ifndef MERGE_H
#define MERGE_H
#include "ErrorCode.h"
#include "../myers_diff/myers.h"
namespace gitstore {

class StoreObject;

class CStoreObjectMerge
{
    using MyersDiffRes = std::vector<emattsan::myers::EditType>;

public:
    CStoreObjectMerge() = delete;

public:
    template<typename...Args>
    static ErrorStatus merge(const StoreObject& value1, const StoreObject& value2,
                      const StoreObject& value_ancestor, StoreObject& value_merge, Args&&...args);

private:
    template<typename T>
    static ErrorStatus mergeSequenceProcess(const T& value1, const T& value2, const T& value_ancestor, T& value_out, const MyersDiffRes &diff1, const MyersDiffRes &diff2);

    template<typename Iter>
    static ErrorStatus findDiffs(Iter&& iter1_begin, Iter&& iter1_end, Iter&& iter2_begin, Iter&& iter2_end, Iter&& iter_ancestor_begin, Iter&& iter_ancestor_end, MyersDiffRes &diff1, MyersDiffRes &diff2);

    static ErrorStatus mergeMapProcess(const StoreObject& value1, const StoreObject& value2,
                                const StoreObject& value_ancestor, StoreObject& value_merge);

    static ErrorStatus mergeListProcess(const StoreObject& value1, const StoreObject& value2,
                                 const StoreObject& value_ancestor, StoreObject& value_merge);
};

template <>
ErrorStatus CStoreObjectMerge::merge<const std::string&>(const StoreObject& value1, const StoreObject& value2,
                  const StoreObject& value_ancestor, StoreObject& value_merge, const std::string& seperator);

template <>
ErrorStatus CStoreObjectMerge::merge(const StoreObject& value1, const StoreObject& value2,
                  const StoreObject& value_ancestor, StoreObject& value_merge);

}
#endif // MERGE_H
